package cn.z2huo.demo.redis.redisson.spring.service;

import cn.z2huo.demo.model.dataobject.user.UserDO;
import cn.z2huo.demo.redis.redisson.spring.util.LockUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 *
 * @author z2huo
 */
@Slf4j
@Service
public class UserServiceImpl {

    @Autowired
    private RedissonClient redissonClient;

    public void updateUser(UserDO userDO) {
        if (StringUtils.isBlank(userDO.getUserCode()) || userDO.getId() == null) {
            throw new RuntimeException("更新用户失败，用户信息无效");
        }

        RLock lock = redissonClient.getLock(LockUtils.getLockKey(userDO.getUserCode()));
        try {
            lock.lock();
            TimeUnit.SECONDS.sleep(5);
            log.info("update user, userCode is {}", userDO.getUserCode());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }

    public void insertUser(UserDO userDO) {
        if (StringUtils.isBlank(userDO.getUserCode()) || userDO.getId() == null) {
            throw new RuntimeException("新增用户失败，用户信息无效");
        }

        String threadName = Thread.currentThread().getName();
        long threadId = Thread.currentThread().threadId();

        RLock lock = redissonClient.getLock(LockUtils.getLockKey(userDO.getUserCode()));
        try {
            // 尝试获取锁，等待时间 10 秒，持有锁时间 100 秒
//            boolean isGetLock = lock.tryLock(5, 100, TimeUnit.SECONDS);
            // 尝试获取锁，等待时间 5 秒
            boolean isGetLock = lock.tryLock(5, TimeUnit.SECONDS);
            if (isGetLock) {
                try {
                    log.info("线程名 {}，线程 ID {}，锁定成功，正在执行业务逻辑", threadName, threadId);
                    TimeUnit.SECONDS.sleep(5);
                } finally {
                    if (lock.isHeldByCurrentThread()) {
                        lock.unlock();
                        log.info("线程名 {}，线程 ID {}，业务处理完成，释放锁", threadName, threadId);
                    }
                }
            } else {
                log.info("线程名 {}，线程 ID {}，无法获取锁，其他线程正在执行该任务。", threadName, threadId);
            }
        } catch (InterruptedException e) {
            log.error("线程名 {}，线程 ID {}，线程中断，未获取锁", threadName, threadId);
            Thread.currentThread().interrupt();
        } finally {
            if (lock.isHeldByCurrentThread()) {
                log.info("lock isHeldByCurrentThread");
                lock.unlock();
            }
        }
    }

}
